/*
    SettingsManager component
    Manages a collection of settings stored as name/value pairs.
*/

using System;
using System.Collections.Generic;
using System.IO;
#if SILVERLIGHT
using System.IO.IsolatedStorage;
#endif

namespace SCG.General
{
    public partial class SettingsManager
    {
        //Public members

        //Constructors
        public SettingsManager()
        {
        }
        public SettingsManager(string fileName)
        {
            FileName = fileName;
        }

        //Access the file name where the settings file should be stored
        public string FileName
        {
            get
            {
                return _fileName;
            }
            set
            {
                _fileName = value;
                LoadSettings();
            }
        }

        //Load/save the settings
        public void LoadSettings()
        {
            _masterSettings.Clear();
#if SILVERLIGHT
            IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
            using (store)
            {
                if (store.FileExists(FileName))
                {
                    int pos;
                    string key, value;
                    IsolatedStorageFileStream stream = store.OpenFile(FileName, FileMode.Open);
                    using (stream)
                    {
                        StreamReader reader = new StreamReader(stream);
                        while (!reader.EndOfStream)
                        {
                            string line = reader.ReadLine();
                            pos = line.IndexOf('=');
                            if (pos > 0)
                            {
                                key = line.Substring(0, pos);
                                value = line.Substring(pos + 1);
                                _masterSettings.Add(key, value);
                            }
                        }
                        reader.Close();
                    }
                }
            }
#else
            if (File.Exists(FileName))
            {
                int pos;
                string key, value;
                string[] lines = File.ReadAllLines(FileName);
                foreach (string line in lines)
                {
                    pos = line.IndexOf('=');
                    if (pos > 0)
                    {
                        key = line.Substring(0, pos);
                        value = line.Substring(pos + 1);
                        _masterSettings.Add(key, value);
                    }
                }
            }
#endif
        }
        public void SaveSettings()
        {
            string line;
#if SILVERLIGHT
            IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
            using (store)
            {
                IsolatedStorageFileStream stream = store.OpenFile(FileName, FileMode.Create);
                using (stream)
                {
                    StreamWriter writer = new StreamWriter(stream);
                    foreach (KeyValuePair<string, string> kvp in _masterSettings)
                    {
                        line = kvp.Key + "=" + kvp.Value;
                        writer.WriteLine(line);
                    }
                    writer.Close();
                }
            }
#else
            List<string> lines = new List<string>();      
            foreach (KeyValuePair<string, string> kvp in _masterSettings)
            {
                line = kvp.Key + "=" + kvp.Value;
                lines.Add(line);
            }           
            lines.Sort();
            string[] lineArray = new string[lines.Count];
            for (int i = 0; i < lines.Count; i++)
                lineArray[i] = lines[i];
            File.WriteAllLines(FileName, lineArray);
#endif
        }

        //Access a string value by raw string key
        public IDictionary<string, string> Settings
        {
            get
            {
                return _masterSettings;
            }
        }

        //Does it contain a specific key?
        public bool ContainsKey(string key)
        {
            return _masterSettings.ContainsKey(key);
        }

        //Access settings values in type-specific ways
        public string Get(string key, string defaultValue)
        {
            if (Settings.ContainsKey(key))
                return Settings[key];
            else
                return defaultValue;
        }
        public void Set(string key, string value)
        {
            Settings[key] = value;
        }

        public bool Get(string key, bool defaultValue)
        {
            if (Settings.ContainsKey(key))
                return Boolean.Parse(Settings[key]);
            else
                return defaultValue;
        }
        public void Set(string key, bool value)
        {
            Settings[key] = value.ToString();
        }

        public SCGColor Get(string key, SCGColor defaultValue)
        {
            if (Settings.ContainsKey(key))
            {
                Tokenizer tok = new Tokenizer(Settings[key]);
                byte a = tok.TokenByte;
                byte r = tok.TokenByte;
                byte g = tok.TokenByte;
                byte b = tok.TokenByte;
                return new SCGColor(a, r, g, b);
            }
            else
                return defaultValue;
        }
        public void Set(string key, SCGColor color)
        {
            Tokenizer tok = new Tokenizer();
            tok.Tokenize(color.A, color.R, color.G, color.B);
            Settings[key] = tok.Result;
        }

        public int Get(string key, int defaultValue)
        {
            if (Settings.ContainsKey(key))
                return Int32.Parse(Settings[key]);
            else
                return defaultValue;
        }
        public void Set(string key, int value)
        {
            Settings[key] = value.ToString();
        }

        public double Get(string key, double defaultValue)
        {
            if (Settings.ContainsKey(key))
                return Double.Parse(Settings[key]);
            else
                return defaultValue;
        }
        public void Set(string key, double value)
        {
            Settings[key] = value.ToString();
        }

        public DateTime Get(string key, DateTime defaultValue)
        {
            if (Settings.ContainsKey(key))
                return new DateTime(Int32.Parse(Settings[key]));
            else
                return defaultValue;
        }
        public void Set(string key, DateTime value)
        {
            Settings[key] = value.Ticks.ToString();
        }

        //Private members
        private Dictionary<string, string> _masterSettings = new Dictionary<string, string>();
        private string _fileName;
    }
}
